package sp.whereru;

import java.io.InputStream;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import android.annotation.TargetApi;
import com.google.android.maps.GeoPoint;

/**
 * This is an abstract class to obtain outdoor walking directions, from the Google Maps Directins API,
 * between 2 coordinates.
 *  
 * @author Nick Luzzi
 * @version 1
 */
public abstract class OutdoorRoute {	
	/**
	 * This method parses xml recieved as an HTTP response from maps.googleapis.com for the 
	 * coordinates of each point in the directions. The directions are returned as an
	 * ArrayList of GeoPoints.
	 * @param startLat the starting latitude coordinate
	 * @param startLon the starting longitude coordinate
	 * @param endLat the destination latitude coordinate
	 * @param endLon the destination longitude coordinate
	 * @return an ArrayList of GeoPoints for each step in the route
	 */
	@TargetApi(8)
	public static ArrayList<GeoPoint> getDirections(double startLat, double startLon, double endLat, double endLon) {

		String url = "http://maps.googleapis.com/maps/api/directions/xml?" +
				"origin=" +startLat + "," + startLon  + "&destination=" + endLat + "," + endLon + "&sensor=false&units=metric&mode=walking";
		String tag[] = { "lat", "lng" };
		ArrayList<GeoPoint> routePoints = new ArrayList<GeoPoint>();
		HttpResponse response = null;
		try {
			HttpClient httpClient = new DefaultHttpClient();
			HttpContext localContext = new BasicHttpContext();
			HttpPost httpPost = new HttpPost(url);
			response = httpClient.execute(httpPost, localContext);
			InputStream in = response.getEntity().getContent();
			DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			Document doc = builder.parse(in);
			if (doc != null) {
				NodeList latList, lonList;
				latList = doc.getElementsByTagName(tag[0]);
				lonList = doc.getElementsByTagName(tag[1]);
				if (latList.getLength() > 0) {
					routePoints = new ArrayList<GeoPoint>();
					for (int i = 0; i < latList.getLength(); i++) {
						Node node1 = latList.item(i);
						Node node2 = lonList.item(i);
						double lat = Double.parseDouble(node1.getTextContent());
						double lng = Double.parseDouble(node2.getTextContent());
						Loc loc = new Loc(lat, lng);
						routePoints.add(loc.toGeoPoint());
					}
				} 
				else {/* No points found*/}
			}
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
		return routePoints;
	}
}
